package com.qinglei.recoup.common.service.impl;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.StorageClass;
import com.qinglei.recoup.common.exception.RecoupException;
import com.qinglei.recoup.common.properties.OssProperties;
import com.qinglei.recoup.common.service.OssService;
import com.qinglei.recoup.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;

@Slf4j
@Service
public class OssServiceImpl implements OssService, InitializingBean, DisposableBean {

    @Resource
    private OssProperties ossProperties;

    private OSS ossClient;

    /**
     * 上传文件
     *
     * @param objectName
     * @param inputStream
     * @param isPublicRead
     */
    @Override
    public String uploadFile(String objectName, InputStream inputStream, boolean isPublicRead) throws RecoupException {
        log.debug("oss upload objectName: {}, isPublicRead: {}", objectName, isPublicRead);
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(ossProperties.getBucketName(), objectName, inputStream);
            if (isPublicRead) {
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
                metadata.setObjectAcl(CannedAccessControlList.PublicRead);
                putObjectRequest.setMetadata(metadata);
            }
            PutObjectResult putObjectResult = this.ossClient.putObject(putObjectRequest);
            log.debug("oss upload objectName: {}, result: {}", objectName, JsonUtils.objectToJson(putObjectResult));
            String url = ossProperties.getAccessDomain() + "/" + objectName;
            log.debug("oss upload return url: {}", url);
            return url;
        } catch (Exception e) {
            log.error("oss upload file error", e);
            throw new RecoupException("文件上传失败");
        }
    }

    @Override
    public void downloadFile(String objectName, File saveFile) throws RecoupException {
        log.debug("oss download objectName:{}, saveFile:{}", objectName, saveFile);
        try {
            GetObjectRequest getObjectRequest = new GetObjectRequest(ossProperties.getBucketName(), objectName);
            ObjectMetadata objectMetadata = ossClient.getObject(getObjectRequest, saveFile);
            log.debug("oss download return:{}", objectMetadata);
        } catch (Exception e) {
            log.error("oss download file error", e);
            throw new RecoupException("文件下载失败");
        }
    }

    @Override
    public boolean isExistFile(String objectName) throws RecoupException {
        log.debug("oss isExistFile objectName:{}", objectName);
        boolean exist;
        try {
            exist = ossClient.doesObjectExist(ossProperties.getBucketName(), objectName);
            log.debug("oss isExistFile return:{}", exist);
        } catch (Exception e) {
            log.error("oss isExistFile file error", e);
            throw new RecoupException("判断文件是否存在失败");
        }
        return exist;
    }

    @Override
    public void destroy() {
        if (this.ossClient != null) {
            this.ossClient.shutdown();
            log.info("ossClient shutdown");
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String endpoint = ossProperties.getEndpoint();
        String accessKeyId = ossProperties.getAccessKeyId();
        String accessKeySecret = ossProperties.getAccessKeySecret();
        this.ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        if (this.ossClient == null) {
            throw new RecoupException("ossClient 构建失败");
        }
        log.info("OssService init complete");
    }
}
